import * as THREE from "three"
import { TourTransitionDirection, TourTransitionType } from "../enum/tourTransition.enum"
import Vectors from "../three/Vectors"
import TourTransitionFactory from "./TourTransitionFactory"

export default class TourDollhousePanTransition {
  settingsData: any
  rotate: any
  stopRotating: any
  type: number
  toIndex: number
  currentTransitionPromise: any
  onStopRequested: () => Promise<void>
  constructor(e, t, i) {
    ;(this.settingsData = e),
      (this.rotate = t),
      (this.stopRotating = i),
      (this.type = TourTransitionType.Burns),
      (this.toIndex = -1),
      (this.currentTransitionPromise = null),
      (this.onStopRequested = () => Promise.resolve())
  }
  get active() {
    return null !== this.currentTransitionPromise
  }
  get promise() {
    return this.currentTransitionPromise ? this.currentTransitionPromise : Promise.resolve()
  }
  async stop() {
    this.currentTransitionPromise && (await this.onStopRequested(), await this.promise, (this.currentTransitionPromise = null))
  }
  start(e) {
    if (this.active) throw Error("Transition already active")
    if (!e.snapshot || !e.nextSnapshot) return (this.currentTransitionPromise = Promise.resolve()), this
    const { deferred: t } = this.build(e.snapshot, e.nextSnapshot, e.panOverrides)
    return (
      (this.currentTransitionPromise = t.then(() => {
        this.currentTransitionPromise = null
      })),
      this
    )
  }
  build(e, t, i) {
    const { panDirection: s, panAngle: n } = i,
      r = TourTransitionFactory.getPanValues(this.settingsData, !0, s, n)
    let o = -1 * r.radiansPerMs
    const a = r.direction
    if (void 0 !== a && a !== TourTransitionDirection.Auto) o *= a
    else if (e && e.metadata.cameraQuaternion && t && t.metadata.cameraQuaternion) {
      const i = Vectors.FORWARD.clone().applyQuaternion(e.metadata.cameraQuaternion),
        s = Vectors.FORWARD.clone().applyQuaternion(t.metadata.cameraQuaternion),
        n = Math.sign(i.cross(s).y)
      o = 0 !== n ? o * n : o
    }
    this.onStopRequested = async () => {
      await this.stopRotating()
    }
    return { deferred: this.rotate(r.ms, new THREE.Vector2(o, 0)) }
  }
}
